import React, { useCallback, useRef, useState, useEffect } from 'react';
import { WidthProvider, Responsive } from 'react-grid-layout';
import { useStore } from '../store/useStore';
import { ComponentType } from '../types/component';
import type { Component as ComponentItem } from '../types/component';
import { Button, Table, Input, Form, Select, DatePicker, message, Tooltip, Space } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { useDrop } from 'react-dnd';
import { 
  CopyOutlined, 
  DeleteOutlined, 
  DragOutlined, 
  EyeOutlined, 
  LockOutlined,
  UnlockOutlined,
  AlignLeftOutlined,
  AlignRightOutlined,
  VerticalAlignTopOutlined,
  VerticalAlignBottomOutlined,
  BorderHorizontalOutlined,
  BorderVerticleOutlined
} from '@ant-design/icons';
import { alignComponents, isComponentInSelectionBox } from '../utils/componentUtils';
import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css';
import './Canvas.css';

const ResponsiveGridLayout = WidthProvider(Responsive);

// 表格列定义
const defaultColumns: ColumnsType<Record<string, any>> = [
  { title: '列1', dataIndex: 'col1', key: 'col1' },
  { title: '列2', dataIndex: 'col2', key: 'col2' }
];

// 表格数据定义
const defaultData = [
  { id: 1, col1: '数据1', col2: '值1' },
  { id: 2, col2: '值2' }
];

// 组件渲染函数
const renderComponent = (type: ComponentType, props: Record<string, unknown>) => {
  const commonProps = {
    style: { width: '100%', ...(props.style as React.CSSProperties) },
    ...props
  };

  switch (type) {
    case ComponentType.BUTTON:
      return <Button {...commonProps}>{props.text || '按钮'}</Button>;
    case ComponentType.SEARCH_BAR:
      return <Input.Search placeholder="搜索..." {...commonProps} />;
    case ComponentType.TABLE: {
      const columns = props.columns || defaultColumns;
      const data = props.data || defaultData;
      return <Table columns={columns as ColumnsType<Record<string, any>>} dataSource={data as Record<string, any>[]} pagination={false} {...commonProps} />;
    }
    case ComponentType.FORM:
      return (
        <Form {...commonProps}>
          <Form.Item label="字段1">
            <Input />
          </Form.Item>
          <Form.Item label="字段2">
            <Input />
          </Form.Item>
        </Form>
      );
    case ComponentType.INPUT:
      return <Input placeholder="请输入..." {...commonProps} />;
    case ComponentType.SELECT:
      return (
        <Select placeholder="请选择..." {...commonProps}>
          <Select.Option value="option1">选项1</Select.Option>
          <Select.Option value="option2">选项2</Select.Option>
        </Select>
      );
    case ComponentType.DATE_PICKER:
      return <DatePicker {...commonProps} style={{ width: '100%' }} />;
    default:
      return <div style={{ padding: 20, background: '#f0f2f5', textAlign: 'center' }}>未知组件</div>;
  }
};

// 画布组件
const Canvas = () => {
  // 从store中获取状态和方法
  const currentPageId = useStore(state => state.app.data.currentPageId);
  const pages = useStore(state => state.app.data.pages);
  const addComponent = useStore(state => state.addComponent);
  const updateComponentLayout = useStore(state => state.updateComponentLayout);
  const setSelectedComponentId = useStore(state => state.setSelectedComponentId);
  const removeComponent = useStore(state => state.removeComponent);
  const selectedComponentId = useStore(state => state.selectedComponentId);
  
  // 本地状态
  const [showGrid, setShowGrid] = useState(true);
  const [selectedComponents, setSelectedComponents] = useState<string[]>([]);
  const [isShiftPressed, setIsShiftPressed] = useState(false);
  const [startPos, setStartPos] = useState<{x: number, y: number} | null>(null);
  const [selectionBox, setSelectionBox] = useState<{x: number, y: number, width: number, height: number} | null>(null);
  const [lockedComponents, setLockedComponents] = useState<Record<string, boolean>>({});
  const [snapToGrid, setSnapToGrid] = useState(true);
  
  const currentPage = currentPageId ? pages[currentPageId] : { components: [] };
  const canvasRef = useRef<HTMLDivElement>(null);
  const gridRef = useRef<HTMLDivElement>(null);

  // 行高和列宽计算
  const rowHeight = 50; // 假设每行高度为50px
  const colWidth = canvasRef.current ? canvasRef.current.offsetWidth / 12 : 50;

  // 处理键盘事件
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      // Shift 键用于多选
      if (e.key === 'Shift') {
        setIsShiftPressed(true);
      }
      
      // Ctrl 键用于复制
      if (e.key === 'Control') {
        // Ctrl 键处理
      }
      
      // Delete 或 Backspace 删除选中组件
      if ((e.key === 'Delete' || e.key === 'Backspace') && selectedComponents.length > 0) {
        // 过滤掉锁定的组件
        const componentsToDelete = selectedComponents.filter(id => !lockedComponents[id]);
        if (componentsToDelete.length > 0) {
          componentsToDelete.forEach(id => {
            removeComponent(id);
          });
          setSelectedComponents([]);
          setSelectedComponentId(null);
          message.success(`已删除 ${componentsToDelete.length} 个组件`);
        } else if (selectedComponents.length !== componentsToDelete.length) {
          message.warning('无法删除锁定的组件');
        }
      }
      
      // Ctrl+C 复制组件
      if (e.key === 'c' && e.ctrlKey && selectedComponents.length > 0) {
        // 将选中的组件存储到剪贴板
        const componentsToCopy = currentPage.components.filter(comp => selectedComponents.includes(comp.id));
        if (componentsToCopy.length > 0) {
          localStorage.setItem('clipboard', JSON.stringify(componentsToCopy));
          message.success(`已复制 ${componentsToCopy.length} 个组件到剪贴板`);
        }
      }
      
      // Ctrl+V 粘贴组件
      if (e.key === 'v' && e.ctrlKey) {
        const clipboard = localStorage.getItem('clipboard');
        if (clipboard) {
          try {
            const componentsToPaste = JSON.parse(clipboard) as ComponentItem[];
            if (Array.isArray(componentsToPaste) && componentsToPaste.length > 0) {
              const newSelectedIds: string[] = [];
              
              componentsToPaste.forEach((comp: ComponentItem) => {
                // 创建新ID和新位置
                const newId = `comp_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
                const newComponent = {
                  ...comp,
                  id: newId,
                  layout: {
                    ...comp.layout,
                    x: (comp.layout.x + 1) % 12, // 稍微偏移位置
                    y: comp.layout.y + 1
                  }
                };
                
                addComponent(newComponent);
                newSelectedIds.push(newId);
              });
              
              setSelectedComponents(newSelectedIds);
              if (newSelectedIds.length === 1) {
                setSelectedComponentId(newSelectedIds[0]);
              }
              
              message.success(`已粘贴 ${componentsToPaste.length} 个组件`);
            }
          } catch (error) {
            console.error('粘贴组件失败:', error);
          }
        }
      }
      
      // Ctrl+A 全选组件
      if (e.key === 'a' && e.ctrlKey) {
        e.preventDefault();
        const allIds = currentPage.components.map(comp => comp.id);
        setSelectedComponents(allIds);
      }
      
      // Escape 取消选择
      if (e.key === 'Escape') {
        setSelectedComponents([]);
        setSelectedComponentId(null);
        setSelectionBox(null);
      }
      
      // 按G键切换网格吸附
      if (e.key === 'g') {
        setSnapToGrid(prev => !prev);
        message.info(`网格吸附已${snapToGrid ? '关闭' : '开启'}`);
      }
    };
    
    const handleKeyUp = (e: KeyboardEvent) => {
      if (e.key === 'Shift') {
        setIsShiftPressed(false);
      }
      if (e.key === 'Control') {
        // Ctrl 键释放处理
      }
    };
    
    window.addEventListener('keydown', handleKeyDown);
    window.addEventListener('keyup', handleKeyUp);
    
    return () => {
      window.removeEventListener('keydown', handleKeyDown);
      window.removeEventListener('keyup', handleKeyUp);
    };
  }, [selectedComponents, currentPage, addComponent, removeComponent, setSelectedComponentId, lockedComponents]);

  // 拖放配置
  const [{ canDrop, isOver }, drop] = useDrop(() => ({
    accept: 'component',
    drop: (item: { type: ComponentType; name: string; defaultLayout?: { w: number; h: number; minW?: number; minH?: number } }, monitor) => {
      const dropPosition = monitor.getClientOffset();
      if (!canvasRef.current || !dropPosition) return;
      
      const canvasRect = canvasRef.current.getBoundingClientRect();
      const gridX = Math.floor((dropPosition.x - canvasRect.left) / (canvasRect.width / 12));
      const gridY = Math.floor((dropPosition.y - canvasRect.top) / 50); // 假设每行高度50px
      
      const newComponent = {
        id: `comp_${Date.now()}`,
        type: item.type,
        name: item.name || item.type,
        props: {},
        layout: {
          x: Math.max(0, gridX),
          y: Math.max(0, gridY),
          w: item.defaultLayout?.w || 4,
          h: item.defaultLayout?.h || 2,
          minW: item.defaultLayout?.minW || 2,
          minH: item.defaultLayout?.minH || 1,
        },
      };

      addComponent(newComponent);
      setSelectedComponentId(newComponent.id);
      setSelectedComponents([newComponent.id]);
      return { id: newComponent.id };
    },
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  }), [addComponent, setSelectedComponentId]);

  // 布局变更处理
  const handleLayoutChange = (layout: any[]) => {
    layout.forEach((item) => {
      const componentId = item.i;
      const component = currentPage.components.find(comp => comp.id === componentId);
      
      if (component && !lockedComponents[componentId]) {
        // 应用网格吸附
        let x = item.x;
        let y = item.y;
        
        if (snapToGrid) {
          x = Math.round(x);
          y = Math.round(y);
        }
        
        updateComponentLayout(componentId, {
          x,
          y,
          w: item.w,
          h: item.h
        });
      }
    });
  };

  // 组件对齐功能
  const handleAlignComponents = (alignment: 'left' | 'right' | 'top' | 'bottom' | 'center-h' | 'center-v') => {
    if (selectedComponents.length <= 1) {
      message.info('需要选择多个组件才能进行对齐操作');
      return;
    }
    
    // 获取第一个选中的组件作为参考组件
    const referenceComponentId = selectedComponents[0];
    
    // 获取所有选中组件
    const componentsToAlign = currentPage.components.filter(comp => 
      selectedComponents.includes(comp.id)
    );
    
    // 执行对齐操作
    const alignedComponents = alignComponents(componentsToAlign, referenceComponentId, alignment);
    
    // 更新布局
    alignedComponents.forEach(comp => {
      if (comp.id !== referenceComponentId) {
        updateComponentLayout(comp.id, comp.layout);
      }
    });
    
    message.success('组件对齐完成');
  };

  // 判断组件是否在选择框内的逻辑，使用工具函数
  const getComponentsInSelectionBox = useCallback(() => {
    if (!selectionBox || !canvasRef.current) return [];
    
    return currentPage.components
      .filter(comp => !lockedComponents[comp.id])
      .filter(comp => 
        isComponentInSelectionBox(comp, selectionBox, rowHeight, colWidth)
      )
      .map(comp => comp.id);
  }, [selectionBox, currentPage.components, lockedComponents, rowHeight, colWidth]);

  // 处理鼠标移动时更新选择框和选中组件
  const handleMouseMove = (e: React.MouseEvent) => {
    if (!startPos || !canvasRef.current) return;
    
    const canvasRect = canvasRef.current.getBoundingClientRect();
    const x = Math.min(startPos.x, e.clientX - canvasRect.left);
    const y = Math.min(startPos.y, e.clientY - canvasRect.top);
    const width = Math.abs(e.clientX - canvasRect.left - startPos.x);
    const height = Math.abs(e.clientY - canvasRect.top - startPos.y);
    
    setSelectionBox({ x, y, width, height });
    
    // 更新选中的组件
    const componentsInBox = getComponentsInSelectionBox();
    if (componentsInBox.length > 0) {
      setSelectedComponents(componentsInBox);
      if (componentsInBox.length === 1) {
        setSelectedComponentId(componentsInBox[0]);
      } else {
        setSelectedComponentId(null);
      }
    }
  };

  // 处理组件点击
  const handleComponentClick = (e: React.MouseEvent, id: string) => {
    e.stopPropagation();
    
    if (isShiftPressed) {
      // Shift 键按下时进行多选
      if (selectedComponents.includes(id)) {
        // 如果已经选中，则取消选中
        setSelectedComponents(selectedComponents.filter(compId => compId !== id));
        if (selectedComponentId === id) {
          setSelectedComponentId(null);
        }
      } else {
        // 如果未选中，则添加到选中列表
        setSelectedComponents([...selectedComponents, id]);
        setSelectedComponentId(id);
      }
    } else {
      // 没有按 Shift 键，则只选中当前组件
      setSelectedComponents([id]);
      setSelectedComponentId(id);
    }
  };

  // 处理画布点击，取消所有选择
  const handleCanvasClick = (e: React.MouseEvent) => {
    if (e.target === canvasRef.current || e.target === gridRef.current) {
      setSelectedComponents([]);
      setSelectedComponentId(null);
    }
  };

  // 处理鼠标按下，开始框选
  const handleMouseDown = (e: React.MouseEvent) => {
    if (e.target === canvasRef.current || e.target === gridRef.current) {
      const canvasRect = canvasRef.current!.getBoundingClientRect();
      setStartPos({
        x: e.clientX - canvasRect.left,
        y: e.clientY - canvasRect.top
      });
      
      // 如果没有按下 Shift 键，则清除之前的选择
      if (!isShiftPressed) {
        setSelectedComponents([]);
        setSelectedComponentId(null);
      }
    }
  };

  // 处理鼠标释放，完成框选
  const handleMouseUp = () => {
    if (selectionBox && startPos) {
      // 获取框选区域内的组件
      const selectedIds = currentPage.components
        .filter((comp: ComponentItem) => {
          if (!canvasRef.current) return false;
          
          const canvasRect = canvasRef.current.getBoundingClientRect();
          const cellWidth = canvasRect.width / 12;
          const cellHeight = 50;
          
          const compLeft = comp.layout.x * cellWidth;
          const compTop = comp.layout.y * cellHeight;
          const compRight = compLeft + comp.layout.w * cellWidth;
          const compBottom = compTop + comp.layout.h * cellHeight;
          
          // 检查组件是否与选择框相交
          return (
            compRight >= selectionBox.x &&
            compLeft <= selectionBox.x + selectionBox.width &&
            compBottom >= selectionBox.y &&
            compTop <= selectionBox.y + selectionBox.height
          );
        })
        .map(comp => comp.id);
      
      if (isShiftPressed) {
        // 如果按下 Shift 键，则添加到现有选择
        setSelectedComponents([...new Set([...selectedComponents, ...selectedIds])]);
      } else {
        // 否则替换现有选择
        setSelectedComponents(selectedIds);
        if (selectedIds.length === 1) {
          setSelectedComponentId(selectedIds[0]);
        } else {
          setSelectedComponentId(null);
        }
      }
    }
    
    setStartPos(null);
    setSelectionBox(null);
  };

  // 复制组件
  const handleCopyComponent = (e: React.MouseEvent, id: string) => {
    e.stopPropagation();
    
    const componentToCopy = currentPage.components.find((comp: ComponentItem) => comp.id === id);
    if (componentToCopy) {
      const newComponent = {
        ...componentToCopy,
        id: `comp_${Date.now()}`,
        layout: {
          ...componentToCopy.layout,
          x: (componentToCopy.layout.x + 1) % 12, // 稍微偏移位置
          y: componentToCopy.layout.y + 1
        }
      };
      
      addComponent(newComponent);
      setSelectedComponentId(newComponent.id);
      setSelectedComponents([newComponent.id]);
      message.success('组件已复制');
    }
  };

  // 切换组件锁定状态
  const toggleComponentLock = (e: React.MouseEvent, id: string) => {
    e.stopPropagation();
    
    setLockedComponents(prev => ({
      ...prev,
      [id]: !prev[id]
    }));
    
    message.success(lockedComponents[id] ? '组件已解锁' : '组件已锁定');
  };

  // 拖放状态样式
  const isActive = canDrop && isOver;
  let backgroundColor = showGrid ? 'var(--canvas-grid-bg)' : '#fff';
  if (isActive) {
    backgroundColor = 'rgba(24, 144, 255, 0.1)';
  }

  return (
    <div 
      className="canvas-container" 
      ref={canvasRef}
      onMouseDown={handleCanvasClick}
      onMouseMove={handleMouseMove}
      onMouseUp={handleMouseUp}
      tabIndex={0} // 使div可以接收键盘事件
    >
      <div className="canvas-toolbar">
        <Space>
          <Tooltip title="显示网格">
            <Button 
              type={showGrid ? "primary" : "default"} 
              icon={<BorderVerticleOutlined />} 
              onClick={() => setShowGrid(!showGrid)}
            />
          </Tooltip>
          <Tooltip title="网格吸附">
            <Button 
              type={snapToGrid ? "primary" : "default"}
              icon={<DragOutlined />} 
              onClick={() => {
                setSnapToGrid(!snapToGrid);
                message.info(`网格吸附已${snapToGrid ? '关闭' : '开启'}`);
              }}
            />
          </Tooltip>
          
          {selectedComponents.length > 1 && (
            <>
              <Tooltip title="左对齐">
                <Button 
                  icon={<AlignLeftOutlined />} 
                  onClick={() => handleAlignComponents('left')}
                />
              </Tooltip>
              <Tooltip title="右对齐">
                <Button 
                  icon={<AlignRightOutlined />} 
                  onClick={() => handleAlignComponents('right')}
                />
              </Tooltip>
              <Tooltip title="顶部对齐">
                <Button 
                  icon={<VerticalAlignTopOutlined />} 
                  onClick={() => handleAlignComponents('top')}
                />
              </Tooltip>
              <Tooltip title="底部对齐">
                <Button 
                  icon={<VerticalAlignBottomOutlined />} 
                  onClick={() => handleAlignComponents('bottom')}
                />
              </Tooltip>
              <Tooltip title="水平居中对齐">
                <Button 
                  icon={<BorderHorizontalOutlined />} 
                  onClick={() => handleAlignComponents('center-h')}
                />
              </Tooltip>
              <Tooltip title="垂直居中对齐">
                <Button 
                  icon={<BorderVerticleOutlined />} 
                  onClick={() => handleAlignComponents('center-v')}
                />
              </Tooltip>
            </>
          )}
        </Space>
      </div>

      <div 
        ref={gridRef}
        className={`canvas-grid ${showGrid ? 'show-grid' : ''}`}
      >
        {drop(
          <div className="canvas-drop-area">
            <ResponsiveGridLayout
              className="layout"
              layouts={{ lg: currentPage.components.map(comp => ({
                i: comp.id,
                x: comp.layout.x,
                y: comp.layout.y,
                w: comp.layout.w,
                h: comp.layout.h,
                minW: comp.layout.minW || 1,
                minH: comp.layout.minH || 1,
                static: lockedComponents[comp.id] || false
              })) }}
              breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
              cols={{ lg: 12, md: 10, sm: 8, xs: 6, xxs: 4 }}
              rowHeight={rowHeight}
              margin={[10, 10]}
              containerPadding={[20, 20]}
              onLayoutChange={handleLayoutChange}
              isDraggable={true}
              isResizable={true}
              useCSSTransforms={true}
              compactType={null}
            >
              {currentPage.components.map((component) => (
                <div 
                  key={component.id} 
                  className={`component-wrapper ${selectedComponents.includes(component.id) ? 'selected' : ''} ${lockedComponents[component.id] ? 'locked' : ''}`}
                  onClick={(e) => handleComponentClick(e, component.id)}
                >
                  <div className="component-content">
                    {renderComponent(component.type, component.props)}
                  </div>
                  {selectedComponents.includes(component.id) && (
                    <div className="component-actions">
                      <Tooltip title="复制">
                        <Button 
                          size="small" 
                          icon={<CopyOutlined />} 
                          onClick={(e) => handleCopyComponent(e, component.id)} 
                        />
                      </Tooltip>
                      <Tooltip title="删除">
                        <Button 
                          size="small" 
                          danger 
                          icon={<DeleteOutlined />} 
                          onClick={(e) => {
                            e.stopPropagation();
                            removeComponent(component.id);
                            setSelectedComponents(prev => 
                              prev.filter(id => id !== component.id)
                            );
                            if (selectedComponentId === component.id) {
                              setSelectedComponentId(null);
                            }
                          }} 
                        />
                      </Tooltip>
                      <Tooltip title={lockedComponents[component.id] ? "解锁" : "锁定"}>
                        <Button 
                          size="small"
                          icon={lockedComponents[component.id] ? <UnlockOutlined /> : <LockOutlined />}
                          onClick={(e) => toggleComponentLock(e, component.id)}
                        />
                      </Tooltip>
                    </div>
                  )}
                </div>
              ))}
            </ResponsiveGridLayout>
          </div>
        )}
        
        {selectionBox && (
          <div 
            className="selection-box"
            style={{
              left: selectionBox.x,
              top: selectionBox.y,
              width: selectionBox.width,
              height: selectionBox.height
            }}
          />
        )}
      </div>
    </div>
  );
};

export default Canvas;